package com.lhn.netty.netty_demo.group_chat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.text.SimpleDateFormat;

/**
 * @author lhn
 * @date 2025/06/03 15:35
 * @since 1.0.0
 **/
public class GroupChatServerHandler extends SimpleChannelInboundHandler <String> {

    /**
     * 定义一个 channle 组, 管理所有的 channel
     * GlobalEventExecutor.INSTANCE 是全局的事件执行器, 单例
     * */
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    // 定义时间格式
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * handlerAdded 当一个 channel 加入到 ChannelGroup 就会执行
     * 将当前 channel 添加到 channelGroup 中
     * */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端 " + ctx.channel().remoteAddress() + " 加入聊天");
        Channel channel = ctx.channel();
        // 将该客户加入聊天的信息推送给其他在线客户
        // channelGroup 的 writeAndFlush 方法会将消息推送给除自己以外的所有 channel, 因此不需要自己遍历
        channelGroup.writeAndFlush("[客户端] " + channel.remoteAddress() + " 加入聊天" + sdf.format(new java.util.Date()) + "\n");
        channelGroup.add(channel);
    }

    /**
     * 断开连接, 提示离线
     * */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端断开连接");
        channelGroup.writeAndFlush("[客户端] " + ctx.channel().remoteAddress() + " 离开聊天" + sdf.format(new java.util.Date()) + "\n");
    }

    // 表示一个 channel 处于活动状态, 提示上线
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + " 上线了");
    }

    /**
     * 表示一个 channel 处于不活动状态, 提示离线
     * */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + " 下线了");
        channelGroup.writeAndFlush("[客户端] " + ctx.channel().remoteAddress() + " 离开聊天" + sdf.format(new java.util.Date()) + "\n");
        System.out.println("当前在线人数: " + channelGroup.size());
    }

    /**
     * 转发消息
     * */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
        // 获取到发送消息的 channel
        Channel channel = channelHandlerContext.channel();
        // 这时我们遍历 channelGroup, 根据不同的情况, 回送不同消息
        channelGroup.forEach(ch -> {
            if (channel != ch) {
                ch.writeAndFlush("[客户] " + channel.remoteAddress() + " 发送了消息: " + s + "\n");
            } else {
                ch.writeAndFlush("[自己] 发送了消息: " + s + "\n");
            }
        });
    }
}